package ldh.im.fxgui.controller;

import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import ldh.im.fxbase.pojo.ImGroup;
import ldh.im.fxbase.pojo.ext.UserType;
import ldh.im.fxbase.util.BeanFactory;
import ldh.im.fxbase.util.RegionUtil;
import ldh.im.fxbase.util.ThreadPoolUtil;
import ldh.im.fxbase.cell.ObjectListCell;
import ldh.im.fxbase.dao.GroupDao;
import ldh.im.fxgui.pojo.*;

import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.WeakHashMap;

/**
 * 消息列表
 */
public class MessageController implements Initializable {

    @FXML private Pane controlPane;
    @FXML private Pane sendMessagePane;
    @FXML private ListView<ImGroup> messageUserList;
    @FXML private TextField searchTextField;

    private ObservableList<ImGroup> mItemsDatas = FXCollections.observableArrayList();
    private FilteredList<ImGroup> filteredData = new FilteredList<>(mItemsDatas, s -> true);
    private SortedList<ImGroup> sortedList = new SortedList<>(filteredData, this::mitemCompartor);
    private WeakHashMap<String, RegionUtil.FxmlBean<Node, SendMessageController>> messageNodeCache = new WeakHashMap<String, RegionUtil.FxmlBean<Node, SendMessageController>>();
    private GroupDao groupDao = BeanFactory.getInstance().getBean(GroupDao.class);

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        messageUserList.setItems(sortedList);
//        messageUserList.setSoftTotal(100);
        messageUserList.setCellFactory(new ObjectListCell<>(mItem -> {
            RegionUtil.FxmlBean<Pane, MItemController> fxmlBean = RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/sub/MItemPane.fxml"));
            fxmlBean.getController().setData(mItem);
            fxmlBean.getController().setMessageController(this);
//            fxmlBean.getNode().setOnMouseClicked(e->{
//                if (e.getButton() != MouseButton.PRIMARY) return;
//                changeUserMessage(mItem);
//            });
            return fxmlBean.getNode();
        }));

        messageUserList.getSelectionModel().selectedItemProperty().addListener((ob, o, n)->{
            changeUserMessage(n);
        });
        controlPane.setOnMouseDragged(e->e.consume());
        controlPane.setOnDragDetected(e->e.consume());

        RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/sub/SendMessagePane.fxml"));

        searchTextField.textProperty().addListener((InvalidationListener)l->{
            String filter = searchTextField.getText().trim();
            if(filter == null || filter.length() == 0) {
                filteredData.setPredicate(s -> true);
            } else {
                filteredData.setPredicate(s -> s.getName().contains(filter));
            }
        });
    }

    public void loadMItemDatas() {
        ThreadPoolUtil.submit(()->{
            try {
                List<ImGroup> mItems = groupDao.getDefaultGroups();
                Platform.runLater(()->mItemsDatas.addAll(mItems));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    public void switchMItem(ImGroup mItem) {
        if (messageUserList.getSelectionModel().getSelectedItem() == mItem && messageUserList.getSelectionModel().getSelectedIndex() == 0) return;
        cleanSearchText();
        if (mItemsDatas.contains(mItem)) {
            List<ImGroup> mItems = mItemsDatas;
            ImGroup item = mItems.stream().filter(m->m.getSoftId().equals(mItem.getSoftId())).findFirst().get();
            messageUserList.getSelectionModel().select(item);
            messageUserList.scrollTo(item);
        } else {
            mItemsDatas.add(mItem);
            messageUserList.getSelectionModel().select(mItem);
            messageUserList.scrollTo(mItem);
        }
    }

    public void reload() {
    }

    public void reloadMItem(ImGroup mItem, boolean reOrder) {
        if (messageUserList.getSelectionModel().getSelectedItem() == mItem && messageUserList.getSelectionModel().getSelectedIndex() == 0 && !reOrder) return;
        mItemsDatas.remove(mItem);
        mItemsDatas.add(mItem);
        messageUserList.getSelectionModel().select(mItem);
        ThreadPoolUtil.submit(()->{
            try {
                groupDao.changeNewMessageUpdateTime(mItem.getId());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    public void remove(ImGroup mItem) {
        int idx = messageUserList.getItems().indexOf(mItem);
        mItemsDatas.remove(mItem);
        if (idx > 0) {
            messageUserList.getSelectionModel().select(idx);
        }
    }

    private List<MItem> loadMItemDatas(int num) {
        List<MItem> datas = new ArrayList();
        for(int i=0; i<num; i++) {
            MItem mItem = new MItem();
            mItem.setName("demo " + i);
            mItem.setCreateDate(LocalDateTime.now());
            mItem.setNewMessageDate(LocalDateTime.now());
            mItem.setNewMessage("hello world");
            mItem.setNewMessageCount(10);
            mItem.setUserType(UserType.User);

            datas.add(mItem);
        }
        return datas;
    }

    private void changeUserMessage(ImGroup mItem) {
        if (mItem == null) return;
        RegionUtil.FxmlBean<Node, SendMessageController> fxmlBeant = messageNodeCache.get(mItem.getName());
        if (fxmlBeant != null) {
            sendMessagePane.getChildren().clear();
            sendMessagePane.getChildren().add(fxmlBeant.getNode());
            return;
        }
        RegionUtil.FxmlBean<Node, SendMessageController> fxmlBean = RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/sub/SendMessagePane.fxml"));
        sendMessagePane.getChildren().clear();
        fxmlBean.getController().setMItem(mItem);
        sendMessagePane.getChildren().add(fxmlBean.getNode());
        fxmlBean.getController().setMessageController(this);
        fxmlBean.getController().loadMessageDatas();
        messageNodeCache.put(mItem.getName(), fxmlBean);
//        System.out.println("cacheMessagePane:" + mItem.getName());
    }

    private int mitemCompartor(ImGroup mitem, ImGroup mItem2) {
        if (mitem.isTop()) return 1;
        if (mItem2.isTop()) return 1;
        return mItem2.getUpdateTime().compareTo(mitem.getUpdateTime());
    }

    private void cleanSearchText() {
        this.searchTextField.setText("");
    }
}
